﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using RichList;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;


namespace Downloader
{
    public partial class MainForm : Form
    {
        //数据层
        DownloaderData m_data;

        //表现层 逻辑层
        public MainForm()
        {
            InitializeComponent();
        }
        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern void DwmEnableBlurBehindWindow(
            IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern void DwmExtendFrameIntoClientArea
        (IntPtr hwnd, ref MARGINS margins);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern bool DwmIsCompositionEnabled(); 
        [StructLayout(LayoutKind.Sequential)]
        public struct MARGINS
        {
            public int Left;
            public int Right;
            public int Top;
            public int Bottom;
        }
        [StructLayout(LayoutKind.Sequential)]
        public class DWM_BLURBEHIND
        {
            public uint dwFlags;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fEnable;
            public IntPtr hRegionBlur;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fTransitionOnMaximized;

            public const uint DWM_BB_ENABLE = 0x00000001;
            public const uint DWM_BB_BLURREGION = 0x00000002;
            public const uint DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004;
        }

        protected override void OnLoad(EventArgs e)
        {
            if (DwmIsCompositionEnabled())
            {
                MARGINS margin = new MARGINS();
                margin.Right = margin.Left = margin.Bottom = margin.Top = -1;
                DwmExtendFrameIntoClientArea(this.Handle, ref margin);

                //DWM_BLURBEHIND blur = new DWM_BLURBEHIND();
                //blur.fEnable = true;
                //blur.dwFlags = DWM_BLURBEHIND.DWM_BB_ENABLE;
                //DwmEnableBlurBehindWindow(this.Handle,blur);

            }
            base.OnLoad(e);
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            base.OnPaintBackground(e);
            if (DwmIsCompositionEnabled())
            {
                e.Graphics.Clear(Color.Black);
            }
        }

        [DllImport("shell32.dll")]
        static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, ShowCommands nShowCmd);

        public enum ShowCommands : int
        {
            SW_HIDE = 0,
            SW_SHOWNORMAL = 1,
            SW_NORMAL = 1,
            SW_SHOWMINIMIZED = 2,
            SW_SHOWMAXIMIZED = 3,
            SW_MAXIMIZE = 3,
            SW_SHOWNOACTIVATE = 4,
            SW_SHOW = 5,
            SW_MINIMIZE = 6,
            SW_SHOWMINNOACTIVE = 7,
            SW_SHOWNA = 8,
            SW_RESTORE = 9,
            SW_SHOWDEFAULT = 10,
            SW_FORCEMINIMIZE = 11,
            SW_MAX = 11
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            m_data = new DownloaderData();
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            //处理线程
            foreach(Download dl in m_data.m_DownloadingSet.Values)
            {
                if(dl.m_status == Download.RUNNING)
                    dl.Suspend();
            }
            
        }

        //richListBox event
        void richListBox_start(object sender, DownloadEventArgv argv)
        {
            this.richListBox1.Items[(int)argv.id]._status = RichListItem.RUNNING;
            this.richListBox1.Items[(int)argv.id]._downloaded = argv.downloadedSize;
            this.richListBox1.Items[(int)argv.id]._totallength = argv.totalSize;
        }

        void richListBox_SliceDone(object sender, DownloadEventArgv argv)
        {
            //MessageBox.Show(argv.downloadedSize);;
            this.richListBox1.Items[(int)argv.id]._downloaded = argv.downloadedSize;
            if (argv.totalSize != 0)
            {
                this.richListBox1.Items[(int)argv.id]._totallength = argv.totalSize;
            }
            
            this.richListBox1.UpdateItemId((int)argv.id);
        }
        void richListBox_Completed(object sender, DownloadEventArgv argv)
        {
            this.richListBox1.Items[(int)argv.id]._status = RichListItem.COMPLETED;
            this.richListBox1.Items[(int)argv.id]._downloaded = argv.downloadedSize;
            this.richListBox1.UpdateItemId((int)argv.id);
        }
        void richListBox_Suspend(object sender, DownloadEventArgv argv)
        {
            this.richListBox1.Items[(int)argv.id]._status = RichListItem.SUSPEND;
            this.richListBox1.Items[(int)argv.id]._downloaded = argv.downloadedSize;
            this.richListBox1.UpdateItemId((int)argv.id);
        }

        void richListBox_Except(object sender, DownloadEventArgv argv)
        {
            this.richListBox1.Items[(int)argv.id]._status = RichListItem.ERROR;
            this.richListBox1.UpdateItemId((int)argv.id);
        }

        /************************************************************************/
        /*                           context菜单                                */
        /************************************************************************/

        //修改list菜单第一项
        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {

            if (this.richListBox1.Selected == null)
            {
                e.Cancel = true;
                return;
            }
            long id = this.richListBox1.Selected._id;
            //MessageBox.Show(m_data.m_DownloadingSet[id].m_status.ToString());
            if (this.m_data.m_DownloadingSet[id].m_status == Download.RUNNING)
            {
                this.contextMenuStrip1.Items[0].Text = "暂停";
            }else if (this.m_data.m_DownloadingSet[id].m_status == Download.COMPLETED)
            {
                this.contextMenuStrip1.Items[0].Text = "重新下载";
            }else
            {
                this.contextMenuStrip1.Items[0].Text = "开始";
            }
        }
        private void StartToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            long id = this.richListBox1.Selected._id;
            
            if (m_data.m_DownloadingSet[id].m_status == Download.RUNNING)
            {
                m_data.m_DownloadingSet[id].Suspend();
            }
            else if(m_data.m_DownloadingSet[id].m_status == Download.SUSPEND)
            {
                m_data.m_DownloadingSet[id].Start();
            }
            else if (m_data.m_DownloadingSet[id].m_status == Download.COMPLETED)
            {
                m_data.m_DownloadingSet[id].Start();
            }
            else if (m_data.m_DownloadingSet[id].m_status == Download.EXCEPT)
            {
                m_data.m_DownloadingSet[id].Start();
            }
        }

        private void DeleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(this.m_data.m_DownloadingSet[this.richListBox1.Selected._id].m_status == Download.RUNNING)
            {
                this.m_data.m_DownloadingSet[this.richListBox1.Selected._id].evt_Completed -= richListBox_Completed;
                this.m_data.m_DownloadingSet[this.richListBox1.Selected._id].evt_Start -=richListBox_start;
                this.m_data.m_DownloadingSet[this.richListBox1.Selected._id].evt_SliceDone -=richListBox_SliceDone;
                this.m_data.m_DownloadingSet[this.richListBox1.Selected._id].evt_Suspend -= richListBox_Suspend;
                this.m_data.m_DownloadingSet[this.richListBox1.Selected._id].evt_Except -= richListBox_Except;
                
                this.m_data.m_DownloadingSet[this.richListBox1.Selected._id].Suspend();
            }
            this.m_data.m_DownloadingSet.Remove(this.richListBox1.Selected._id);
            this.richListBox1.Items.RemoveId(this.richListBox1.Selected._id);
            this.richListBox1.SelectedInex = -1;
        }
        private void OpenFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string filepath = this.m_data.m_DownloadingSet[this.richListBox1.Selected._id].m_localpath;
            string filename = this.m_data.m_DownloadingSet[this.richListBox1.Selected._id].m_localfilename;
            ShellExecute(IntPtr.Zero, null, filename, null, filepath, ShowCommands.SW_SHOWNORMAL);
        }

        private void OpenDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string filepath = this.m_data.m_DownloadingSet[this.richListBox1.Selected._id].m_localpath;
            ShellExecute(IntPtr.Zero, null, "", null, filepath, ShowCommands.SW_SHOWNORMAL);
        }


        /************************************************************************/
        /*                             主菜单                                   */
        /************************************************************************/

        private void NewTaskToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NewTaskForm form = new NewTaskForm();
            form.StartPosition = FormStartPosition.CenterParent;
            form.ShowDialog(this);

            if (form.isok)
            {
                string filename1;
                string filename2;
                form.filename = form.filename.Trim();

                int p = form.filename.LastIndexOf('.');
                if (p == -1)
                {
                    filename1 = form.filename;
                    filename2 = "";
                }
                else
                {
                    filename1 = form.filename.Substring(0, p);
                    filename2 = form.filename.Substring(p);
                }

                string filename = form.filename;
                if (File.Exists(form.dirname + "\\" + form.filename))
                {
                    string conffilename = form.dirname + "\\" + form.filename + Download.cofig_sufix;
                    bool b_continue = false;
                    if (File.Exists(conffilename))
                    {
                        if (ConfigFile.ReadUrl(conffilename) == form.url)
                        {
                            if (DialogResult.OK == MessageBox.Show("检测到中断任务，是否继续下载" + filename, "Downloader", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2))
                            {
                                b_continue = true;
                            }
                        }
                    }
                    if (!b_continue)
                    {
                        for (int i = 1; i < 100; ++i)
                        {
                            filename = filename1 + "(" + i + ")" + filename2;
                            if (!File.Exists(form.dirname + "\\" + filename))
                            {
                                break;
                            }
                        }
                        if (DialogResult.OK != MessageBox.Show("此文件已经存在，是否重命名为" + filename, "Downloader", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2))
                        {
                            return;
                        }
                    }
                }

                Download dl = new Download(richListBox1.Items.GetNextIdleId(), form.dirname, filename, form.url);
                m_data.m_DownloadingSet.Add(dl.m_id, dl);
                Icon largeIcon;
                Icon smallIcon;
                string des;
                IconUtil.GetExtsIconAndDescription(filename2, out largeIcon, out smallIcon, out des);
                //RichListItem item = new RichListItem(dl.m_id,dl.m_localfilename,0,dl.m_filelength,Downloader.Properties.Resources.device_ipad);
                RichListItem item = new RichListItem(dl.m_id, dl.m_localfilename, 0, dl.m_filelength, largeIcon == null ? Downloader.Properties.Resources.device_ipad : largeIcon.ToBitmap());

                richListBox1.Items.Add(item);


                dl.evt_Start += richListBox_start;
                dl.evt_SliceDone += richListBox_SliceDone;
                dl.evt_Completed += richListBox_Completed;
                dl.evt_Suspend += richListBox_Suspend;
                dl.evt_Except += richListBox_Except;
                dl.Start();
            }
        }

        private void RootTaskToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            this.TaskStartToolStripMenuItem.Enabled = false;
            this.TaskSuspendToolStripMenuItem.Enabled = false;
            this.TaskRestartToolStripMenuItem.Enabled = false;
            this.TaskDeleteToolStripMenuItem.Enabled = false;
            if (this.richListBox1.Selected == null)
            {
                return;
            }
            long id = this.richListBox1.Selected._id;
            if (this.m_data.m_DownloadingSet[id].m_status == Download.RUNNING)
            {
                this.TaskSuspendToolStripMenuItem.Enabled = true;
            }
            else if (this.m_data.m_DownloadingSet[id].m_status == Download.COMPLETED)
            {
                this.TaskRestartToolStripMenuItem.Enabled = true;
                this.TaskDeleteToolStripMenuItem.Enabled = true;
            }
            else
            {
                this.TaskStartToolStripMenuItem.Enabled = true;
                this.TaskDeleteToolStripMenuItem.Enabled = true;
            }
        }
        private void 关于AToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string s = "";
            foreach(long one in m_data.m_DownloadingSet.Keys.ToArray<long>())
            {
                s += "[" + one.ToString() + ":" + m_data.m_DownloadingSet[one].m_localfilename+ "]\n";
            }
            MessageBox.Show(s);
        }

        private void AboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StartToolStripMenuItem1_Click(null, null);
        }

        private void TaskStartToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StartToolStripMenuItem1_Click(null, null);
        }

        private void TaskSuspendToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StartToolStripMenuItem1_Click(null, null);
        }

        private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void TaskDeleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DeleteToolStripMenuItem_Click(null, null);
        }





    }
}
